package steed.ext.listener;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;

import javax.servlet.ServletContext;
import javax.servlet.ServletContextEvent;
import javax.servlet.annotation.WebListener;

import org.h2.util.New;

import steed.action.annotation.Power;
import steed.exception.PathIsTopException;
import steed.ext.domain.system.Path_Power;
import steed.ext.domain.user.Role;
import steed.ext.domain.user.User;
import steed.hibernatemaster.util.DaoUtil;
import steed.listener.SystemInitListener;
import steed.util.UtilsUtil;
import steed.util.base.BaseUtil;
import steed.util.base.PathUtil;
import steed.util.digest.AESUtil;
import steed.util.digest.Md5Util;
/**
 * 
 * @author 战马
 *        battle_steed@163.com
 */
@WebListener
public class SteedExtInitListener extends SystemInitListener{
	
	private void addPower(List<Path_Power> root,Set<steed.ext.domain.user.Power> set){
		if(root == null){
			return;
		}
		for(Path_Power temp:root){
			if(temp.getLevel() == 0){
				continue;
			}
			set.add(temp.convert2Power());
			addPower(temp.getSonList(),set);
		}
	}
	
	@Override
	public void contextInitialized(ServletContextEvent event) {
		super.contextInitialized(event);
		DaoUtil.setAutoManagTransaction(false);
		try{
			ServletContext servletContext = event.getServletContext();
			List<Path_Power> path_PowerList = getPath_PowerList(servletContext);
			servletContext.setAttribute("Path_PowerList", path_PowerList);
			
			Set<steed.ext.domain.user.Power> userPower = new HashSet<>();
			addPower(path_PowerList,userPower);
			servletContext.setAttribute("userPowers", userPower);
			
			User queryCondition = new User("admin");
			if (DaoUtil.listOneFields(queryCondition, "password") == null) {
				BaseUtil.getLogger().debug("开始初始化admin数据...");
				Role role = new Role();
				role.setName("超级管理员");
				role.setIsSystemRole(true);
				role.setPowerSet(userPower);
				role.setDescription("超级管理员");
				role.save();
				
				Set<Role> hashSet = new HashSet<>();
				hashSet.add(role);

				queryCondition.setPassword(AESUtil.aesEncode(Md5Util.Md5Digest("123456")));
				queryCondition.setRoleSet(hashSet);
				queryCondition.updateNotNullField(null);
			}
			
		}catch(Error e){
			BaseUtil.getLogger().error("web应用启动出错!",e);
			throw e;
		}finally {
			DaoUtil.managTransaction();
			UtilsUtil.releaseUtils();
		}
		
	}
	
	/**
	 * 把action注解中的权限保存到数据库，不用另外在数据库手动加权限记录
	 * @param path_PowerList
	 */
	/*public void saveNnnotationPower2Database(List<Path_Power> path_PowerList) {
		if (CollectionsUtil.isListEmpty(path_PowerList)) {
			return;
		}
		for (Path_Power p:path_PowerList) {
			if (DaoUtil.get(Power.class, p.getPower()) == null) {
				new Power(p.getPower()).save();
			}
			saveNnnotationPower2Database(p.getSonList());
		}
	}*/
	
	public List<Path_Power> getPath_PowerList(ServletContext servletContext){
		List<Path_Power> list = new ArrayList<Path_Power>();
		
		Map<String, Path_Power> map = evalPath_Power2Domain(servletContext);
		for (Entry<String, Path_Power> e:map.entrySet()) {
			
			Path_Power paraent = getParaent(e.getKey(), map);
			//只添加顶级路径，不是顶级路径则放到parent中
			if (paraent != null) {
				paraent.addSon(e.getValue());
			}else {
				list.add(e.getValue());
			}
		}
		return list;
	}

	@SuppressWarnings("unchecked")
	public Map<String, Path_Power> evalPath_Power2Domain(ServletContext servletContext) {
		List<Object> listAllCustomField = DaoUtil.listAllCustomField(null, steed.ext.domain.user.Power.class, "name");
		Map<String, Path_Power> map = new HashMap<String, Path_Power>();
		Map<String, Power> scanActionPower = (Map<String, Power>)servletContext.getAttribute("path_powerMap");
		Map<String,Power> power4Save = new HashMap<>();
		for (Entry<String, Power> e:scanActionPower.entrySet()) {
			Power power = e.getValue();
			if (!listAllCustomField.contains(power.value())) {
				power4Save.put(power.value(),power);
				/*if (!PropertyUtil.getBoolean("devMode")
						&&DaoUtil.get(steed.ext.domain.user.Power.class, power.value()) == null) {
					continue;
				}*/
			}
			Path_Power path_Power = new Path_Power();
			String path = e.getKey();
			path_Power.setPath(path);
			path_Power.setPower(power.value());
			path_Power.setLevel(power.level());
			
			map.put(path, path_Power);
		}
		for(Entry<String, Power> a:power4Save.entrySet()){
			Power temp = a.getValue();
			new steed.ext.domain.user.Power(temp.value(),temp.level()).save();
		}
		return map;
	}
	
	private Path_Power getParaent(String path,Map<String, Path_Power> map){
		try {
			String paraentPath = PathUtil.getParaentPath(path);
			
			if (!path.endsWith("/")) {
				paraentPath += "/";
			}
			Path_Power power = map.get(paraentPath);
			if (power == null) {
				return getParaent(paraentPath, map);
			}else {
				return power;
			}
			
		} catch (PathIsTopException e1) {
			return null;
		}

	}
	
}
